This code comes from the scene titled "Secretary", from my game "A Mess O'Trouble". This is a very complex scene that demonstrates the advanced use of variables.
In this scenario, the player has entered the Department of Security and is met by a secretary at his desk. The player needs two things here: The secret password to enter the President's headquarters; and a special admittance form to enter the Utilities Department. The form must be filled out, and signed by the chief of security. When the player asks for either of these things, the secretary says he must cleared it with the chief, and leaves the room. When he returns, he tells the player that his request has been denied.
In order to get the form and secret password, the player must ask again for these things, then explore the secretary's desk while the secretary is out of the room. He can also use the typewriter during this time. If he takes too long, the secretary returns and stops him.
IF{LOOP#=0}THEN
IF{T8#<2}THEN
MOVE{DARK}TO{SCENE@}
MOVE{PLAYER@}TO{RANDOMSCN@}
EXIT
MOVE{DARK}TO{STORAGE@}
IF{D1#=0}THEN
MOVE{SECRETARY.1}TO{SCENE@}
END
END
This section of code handles the player's premature appearance in the scene. This game has Jump Doors that can move a player to a randomly chosen scene. However, some scenes are supposed to be closed to the player until he has completed some puzzle. In this case, this part of the city can only be accessed after the player has obtained a validated tram pass. So this section of code first checks to see if the player has obtained a tram pass and had it validated. It does this by checking variable T8, which is the tram pass variable.
If T8 is less than 2, meaning the player has no validated tram pass, then the scene is blacked out by moving the DARK object to the scene, and the player is moved to another random scene. The program then EXITs. If T8 equals 2 or more, than the DARK is returned to storage and the program continues.
The program then checks the status of variable D1. This variable determines whether or not the secretary object is supposed to be in the scene. (The secretary is an Object, NOT a Character! This gives the player complete control over the secretary's actions.) If D1 is zero, if means the secretary is supposed to be in the scene, and the program is instructed to move that object to the scene.
IF{D1#=1}THEN
LET{D2#=D2#+1}
END
When the secretary leaves the room, D1 is set to 1. Variable D2 is a counter that counts the number of actions the player takes in the scene. This brief conditional statement checks to see if the secretary is out of the room (D1=1), and if so, adds one point to the D2 counter. In this way, I can simulate the passage of time. The player only has a limited number of moves between the time the secretary leaves, and when the secretary returns. D2 is only updated when D1#=1.
IF{LOOP#=0}OR{TEXT$=LOOK}THEN
IF{TEXT$=DESK}OR{TEXT$=DRAWER}THEN
PRINT{........................................}
IF{SECRETARY.1=SCENE@}THEN
PRINT{SECRETARY: "Get away from there or I'll call the guards!"}
EXIT
IF{FORM=STORAGE@}AND{F9#<1}THEN
MOVE{FORM}TO{SCENE@}
PRINT{There is a Utility Area Admittance form in the desk.}
PRINT{SECRETARY: "Get away from there or I'll call the guards!"}
EXIT
IF{FORM=STORAGE@}AND{F9#<1}THEN
MOVE{FORM}TO{SCENE@}
PRINT{There is a Utility Area Admittance form in the trash.}
EXIT
PRINT{There is nothing of interest in the wastebasket.}
EXIT
PRINT{You are in the offices of the Department of Security. There is a closed door to the SOUTH, and the exit is NORTH.}
IF{D3#=1}THEN
PRINT{........................................}
PRINT{SECRETARY: "Oh there you are! The boss turned down your request. She says you're not a good security risk."}
PRINT{"Do you want to try again?"}
LET{D3#=0}
EXIT
IF{SECRETARY.1=SCENE@}THEN
PRINT{........................................}
PRINT{SECRETARY: "What can I do for you?"}
END
END
The LOOK code here is fairly complex. It must print a scene description when the player enters the scene, or when the player uses the LOOK command. The secretary's greeting to the player varies, and is a part of the scene description, so the scene description also varies. In addition, this section of code handles the player's request to look in the desk, look in the trash, etc.
The first nested statement checks to see if the player used the words DESK or DRAWER. The next statement checks to see if the secretary is in the scene, and if so, stops the player from taking that action.
The next condition checked is the status of the form. Variable F9 tracks whether the form has been used already. If the form is in storage, AND has not already been used (F9#<1), then form is moved to the scene, and the player is told that he has found a Utility Area Admittance form in the desk. If either of those conditions is not true, then the player is told that the desk is empty. The program then EXITs.
If LOOK is not followed by DESK or DRAWER, then the next thing the program checks is whether any words have been used that indicate the player wants to look in the TRASH. The form can be found in either the desk or the trash, whichever the player looks into first. So this section of the code repeats the steps used for looking in the desk.
Finally, if there are no modifiers used with LOOK, then the scene description is printed. The secretary's greeting is included in the scene description. Since it is possible for the player to leave the scene while the secretary is out of the room, and return later, the greeting must reflect this. So variable D3 tracks that condition, and is checked here. If D3#=1, meaning that the player did indeed leave while the secretary was gone, and is now returning, a special greeting is printed which refers to the fact the player left prematurely, tells him that he request has been denied. The variable is then reset to zero. If D3 does not equal one, then the standard greeting is printed: "What can I do for you?"
The entire loop-zero/look code closes with END. In this way, if the player has dropped something in the scene earlier, the object will automatically be mentioned in the scene text.
IF{D2#=5}THEN
PRINT{..........................................}
SOUND{DOOR OPENING}
MOVE{SEC.DOOR}TO{STORAGE@}
MOVE{SECRETARY.2}TO{SCENE@}
MOVE{SEC.DOOR}TO{SCENE@}
SOUND{DOOR CLOSING}
MOVE{SECRETARY.2}TO{STORAGE@}
PRINT{The door opens and the secretary enters the room.}
MOVE{SECRETARY.1}TO{SCENE@}
LET{D1#=0}
LET{D2#=0}
LET{A1#=RANDOM#}
IF{A1#>80}THEN
PRINT{SECRETARY: "I'm sorry, the boss says No. She doesn't think you're a good security risk."}
PRINT{"Perhaps you could try again later."}
EXIT
IF{A1#>50}AND{A1#<81}THEN
PRINT{SECRETARY: "I'm sorry, the boss says you aren't cleared for that. Request denied."}
PRINT{"Perhaps you could try again later."}
EXIT
IF{A1#>20}AND{A1#<51}THEN
PRINT{SECRETARY: "I'm sorry, the boss refuses to clear you on that. Request denied."}
PRINT{"Perhaps you could try again later."}
EXIT
IF{A1#<21}THEN
PRINT{SECRETARY: "I'm sorry, the boss is too busy to issue the necessary clearance right now. Request denied."}
PRINT{"Perhaps you could try again later."}
EXIT
END
When variable D2 reaches five, it triggers this section of code. The secretary is returned to the scene, D1 and D2 are reset to zero, and one of four randomly chosen replies is printed. Resetting D1 allows the player to repeat the steps needed to convince the secretary to leave the room. Since variable D2 is a counter that controls the reappearance of the secretary, it too must be reset now that the secretary is back.
World Builder generates a random number between 1 and 100 each time you use RANDOM#.
When you want to have several response randomly selected, assign a variable to contain the random number. If you merely use RANDOM#, then a different number would be chosen each time, giving unsatisfactory results. But when you assign a random number to a variable, that variable holds whatever random number is chosen, until such time as you reassign it. The same variable can usually be used to hold random numbers throughout the game.
After a random number has been assigned to variable A1, there are four conditional statements that determine which response to print. If A1 is more than 81, the first response is printed. If A1 is less than 80, AND more than 50, the second response is printed. If it is less than 51, AND more than 20, the third response is printed. Finally, if A1 is less than 21 the fourth response will be printed.
Of course, you can write code that will offer as many possible response as you like. You can also set the percentages to favor one or more responses over others. The only limit is your imagination, and the amount of available code space in the scene.
I could have used only one standard response in this setting. But using several randomly picked responses made the secretary seem more life-like, and less boring.
This entire section of code must come before any codes that handle the player's actions or conversation. In fact, I see now that it should have been placed BEFORE the LOOK code! This is another example of how you can be tripped up by complex code. As it is now, if the player tries to look in the desk or in the trash, that action will intercept the program before it reaches this section of code. If variable D2 is at five when the player does that, the variable will reach five or more before this code is reached. Since this code only returns the secretary to the scene when D2 is EXACTLY five, if it goes above that then the secretary will never return! The chances of this happening in precisely this way are small, and it wouldn't cause serious problems if it did. But it should still be corrected. (This has been corrected in later versions of the game.)
I corrected it by simply changing it to D2#>4. If I do this, looking in the desk or trash might still allow D2 to go higher than 5, but it wouldn't matter since the code would kick in any time D2 is higher than 4.
IF{TEXT$=SEARCH}THEN
PRINT{.........................................}
IF{SECRETARY.1=SCENE@}THEN
PRINT{SECRETARY: "Stop snooping around!"}
EXIT
PRINT{There is a typewriter on the desk, to the EAST.}
PRINT{And there is a wastebasket in the corner.}
EXIT
The search code checks to see if the secretary is in the scene, and if so, stops the player from searching.
PRINT{SECRETARY: "Stop that! I can't let you use my typewriter."}
EXIT
MOVE{PLAYER@}TO{TYPEWRITER}
EXIT
The player can use any of these command words, and if the secretary is not in the scene, the player will be moved to a scene where he is sitting at the typewriter. In that scene the player can then use the typewriter to fill out the form, and discover the secret password.
IF{TEXT$=SOUTH}THEN
PRINT{..........................................}
IF{SECRETARY.1=SCENE@}THEN
PRINT{SECRETARY: "You can't go in there! It's not permitted!"}
EXIT
PRINT{The secretary and his boss are in there. If you go in they'll have you thrown out, or arrested!}
EXIT
This code gives appropriate responses when the player tries to go south through the door to the chief's office.
IF{CLICK$=SEC.DOOR}THEN
PRINT{..........................................}
IF{SECRETARY.1=SCENE@}THEN
PRINT{SECRETARY: "Stay out of there! That's a private office, you're not permitted to enter!"}
EXIT
PRINT{The secretary and his boss are in there, so you'd better not open the door.}
EXIT
IF{CLICK$=SEC.TYPEWRITER}THEN
PRINT{..........................................}
IF{SECRETARY.1=SCENE@}THEN
PRINT{SECRETARY: "Leave my typewriter alone!"}
EXIT
PRINT{The typewriter is unattended.}
EXIT
IF{CLICK$=SEC.TRASH}THEN
PRINT{..........................................}
IF{SECRETARY.1=SCENE@}THEN
PRINT{SECRETARY: "Get away from there or I'll call the guards!"}
EXIT
PRINT{There is a wastebasket here.}
EXIT
IF{CLICK$=SEC.CHAIR}THEN
PRINT{..........................................}
IF{SECRETARY.1=SCENE@}THEN
PRINT{SECRETARY: "Stop that! Leave my chair alone!"}
EXIT
PRINT{The secretary's chair is empty.}
EXIT
These sections of code handle the object descriptions when the player clicks on them. If the secretary is in the scene, the player is prevented from getting a description of the object.
IF{TEXT$=GET}OR{TEXT$=TAKE}OR{TEXT$=MOVE}THEN
PRINT{..........................................}
IF{SECRETARY.1=SCENE@}THEN
PRINT{SECRETARY: "Leave that alone!"}
EXIT
IF{TEXT$=TYPEWRITER}THEN
PRINT{The typewriter is bolted to the desk, you can't move it.}
EXIT
IF{TEXT$=CHAIR}THEN
PRINT{You can't move the chair.}
EXIT
IF{TEXT$=WASTE}OR{TEXT$=BASKET}THEN
PRINT{You can't take the wastebasket.}
EXIT
END
This code handles any attempt to move the equipment in the office. Again, if the secretary is in the scene, the action is blocked.
PRINT{The secretary pushes a hidden button, and an electrode in the ceiling zaps you silly!}
PRINT{SECRETARY: "We don't tolerate that kind of behavior around here!"}
EXIT
PRINT{Doing that might draw unwanted attention to your activity.}
EXIT
This code handles any use of weapons, whether the player is attacking the secretary or merely trying to shoot or break an object.
IF{TEXT$=READ}THEN
IF{TEXT$=FORM}THEN
PRINT{.......................................}
PRINT{The form is just a typical government form, that allows the bearer to enter the Utility Area.}
IF{F8#<1}THEN
PRINT{All the necessary spaces are blank.}
EXIT
EXIT
END
In some cases the player may try to read the form. This code handles that, and tells him if the form has been filled out or not.
IF{TEXT$=GIVE}OR{TEXT$=OFFER}THEN
PRINT{..........................................}
IF{SECRETARY.1=SCENE@}THEN
IF{TEXT$=FORM}AND{FORM=PLAYER@}THEN
PRINT{SECRETARY: "You're not supposed to have that!"}
MOVE{FORM}TO{STORAGE@}
LET{F9#=0}
PRINT{The secretary takes the form and throws it away.}
EXIT
IF{TEXT$=CARD}AND{SHEKCARD=PLAYER@}THEN
PRINT{SECRETARY: "You're a friend of Shek Varta? I'm impressed! But even she can't get you a security clearance."}
EXIT
PRINT{SECRETARY: "Don't bother trying to bribe me, it won't work!"}
EXIT
END
This section handles any attempt to give something to the secretary. If it is the form, the player takes the form away and F9 is reset to zero. The player must then repeat the steps needed to get another form. If the player tries to give Shek's card to the secretary, the secretary responds accordingly. Anything else that is offered to the secretary is treated as a bribe attempt.
PRINT{SECRETARY: "I'll have to clear that with the boss. It could take a few minutes. Wait here."}
END
IF{A1#>40}AND{A1#<61}THEN
PRINT{SECRETARY: "That has to be approved by the chief of Security. Wait here."}
END
IF{A1#<41}THEN
PRINT{SECRETARY: "Wait here and I'll see if the boss will approve that."}
END
MOVE{SECRETARY.1}TO{STORAGE@}
MOVE{SECRETARY.2}TO{SCENE@}
SOUND{WAIT HERE.1}
SOUND{DOOR OPENING}
MOVE{SEC.DOOR}TO{STORAGE@}
MOVE{SECRETARY.2}TO{STORAGE@}
MOVE{SEC.DOOR}TO{SCENE@}
SOUND{DOOR CLOSING}
LET{D1#=1}
EXIT
END
This section handles any other uses of the words FORM, PASSWORD, ADMITTANCE, YES and SIGNATURE. The secretary responds from one of three randomly chosen sentences, and leaves the room. Variable D1 is set to one, indicating that the secretary has left. Any further actions will start up the counter, D2.
IF{TEXT$=NORTH}THEN
LET{D1#=0}
LET{D2#=0}
IF{SECRETARY.1>SCENE@}THEN
LET{D3#=1}
END
END
If the player exits the scene at any time, variables D1 and D2 are reset to zero. If the secretary is out of the scene at the time, D3 is set to one.
IF{TEXT$==NO}THEN
PRINT{..........................................}
IF{SECRETARY.1=SCENE@}THEN
PRINT{SECRETARY: "Well, if you change your mind, just let me know."}
PRINT{The secretary continues working.}
EXIT
END
If the player says "No" to any question or statement by the secretary, this standard reply is printed.
IF{TEXT$=INFO}OR{TEXT$=ASK}OR{TEXT$=TALK}THEN
PRINT{..........................................}
IF{SECRETARY.1=SCENE@}THEN
PRINT{SECRETARY: "Anyone wishing to enter restricted areas of the city must be cleared by Security."}
EXIT
END
This handles the player's attempt to talk to the secretary.
IF{TEXT$=OPEN}THEN
PRINT{........................................}
IF{TEXT$=DESK}OR{TEXT$=DRAWER}THEN
IF{SECRETARY.1=SCENE@}THEN
PRINT{SECRETARY: "Get away from there or I'll call the guards!"}
EXIT
IF{FORM=STORAGE@}AND{F9#<1}THEN
MOVE{FORM}TO{SCENE@}
PRINT{There is a Utility Area Admittance form in the desk.}
EXIT
PRINT{There is nothing of interest in the desk.}
EXIT
IF{TEXT$=DOOR}THEN
PRINT{..........................................}
IF{SECRETARY.1=SCENE@}THEN
PRINT{SECRETARY: "Stay out of there! That's a private office, you're not permitted to enter!"}
EXIT
PRINT{The secretary and his boss are in there, so you'd better not open the door.}
EXIT
PRINT{What do you want to open?}
EXIT
This code handles any attempt to open things. The only things that can be opened in this scene are the desk and the door to the chief's office. Opening the desk reveals the form, if the player hasn't already found it.